COVID-19 dashboard
This COVID-19 dashboard was created as the final assignment for the Data Analysis course at Utah Valley University, which is instructed by Dr. Zahn. The information here provides an overlook of the COVID-19 data by providing the user with graphs, figures, a map, etc., all of which were built using the Rmarkdown framework in R Studio
Reproduction
All data was obtained freely online. The code behind the dashboard is available here
Data
The input data for this dashboard is the coronavirus R package (dev version). The data and dashboard is refreshed on a daily bases. The raw data pulled from the Johns Hopkins University Center for Systems Science and Engineering (JHU CCSE) Coronavirus repository
Packages
Useful Links
---
title: "COVID-19"
author: by - Jacob James
output:
flexdashboard::flex_dashboard:
orientation: rows
social: menu
source_code: embed
vertical_layout: fill
theme: flatly
---
```{r, include=FALSE}
#load 'coronavirus' package (if not already above)
devtools::install_github("covid19r/coronavirus", force = TRUE)
```
```{r setup, include=FALSE}
#load packages
library(flexdashboard)
library(coronavirus)
library(tidyr)
library(DT)
library(dplyr)
library(knitr)
library(plotly)
library(testthat)
library(devtools)
library(remotes)
library(leaflet)
library(leafpop)
library(purrr)
library(shinythemes)
library(xaringan)
```
```{r, include=FALSE}
#check if there is a data update on the Github version
coronavirus::update_datasets(silence = TRUE)
#load data set
data("coronavirus")
`%>%` <- magrittr::`%>%`
```
```{r, include=FALSE}
#preview data set
head(coronavirus)
tail(coronavirus)
```
```{r, include=FALSE}
#Parameters
confirmed_color <- "#bf7343"
active_color <- "#3966ad"
recovered_color <- "#269928"
death_color <- "#661d1b"
#Data
df <- coronavirus %>%
#dplyr::filter(date == max(date)) %>%
dplyr::group_by(Country.Region, type) %>%
dplyr::summarise(total = sum(cases)) %>%
tidyr::pivot_wider(names_from = type,
values_from = total) %>%
dplyr::mutate(unrecovered = confirmed - ifelse(is.na(recovered), 0, recovered) - ifelse(is.na(death), 0, death)) %>%
dplyr::arrange(-confirmed) %>%
dplyr::ungroup() %>%
dplyr::mutate(country = dplyr::if_else(Country.Region == "United Arab Emirates", "UAE", Country.Region)) %>%
dplyr::mutate(country = dplyr::if_else(country == "Mainland China", "China", country)) %>%
dplyr::mutate(country = dplyr::if_else(country == "North Macedonia", "N.Macedonia", country)) %>%
dplyr::mutate(country = trimws(country)) %>%
dplyr::mutate(country = factor(country, levels = country))
df_daily <- coronavirus %>%
dplyr::group_by(date, type) %>%
dplyr::summarise(total = sum(cases, na.rm = TRUE)) %>%
tidyr::pivot_wider(names_from = type,
values_from = total) %>%
dplyr::arrange(date) %>%
dplyr::ungroup() %>%
dplyr::mutate(active = confirmed - death - recovered) %>%
dplyr::mutate(confirmed_cum = cumsum(confirmed),
death_cum = cumsum(death),
recovered_cum = cumsum(recovered),
active_cum = cumsum(active))
df1 <- coronavirus %>% dplyr::filter(date == max(date))
```
```{r, echo=FALSE}
#trajectory plot data prep
df_china <- coronavirus %>% dplyr::filter(type == "confirmed", Country.Region == "China") %>%
dplyr::group_by(date) %>%
dplyr::summarise(cases = sum(cases)) %>%
dplyr::ungroup() %>%
dplyr::arrange(date) %>%
dplyr::mutate(china = cumsum(cases)) %>%
dplyr::filter(china > 100) %>%
dplyr::select(-cases, -date)
df_china$index <- 1:nrow(df_china)
df_uk <- coronavirus %>% dplyr::filter(type == "confirmed", Country.Region == "United Kingdom") %>%
dplyr::group_by(date) %>%
dplyr::summarise(cases = sum(cases)) %>%
dplyr::ungroup() %>%
dplyr::arrange(date) %>%
dplyr::mutate(uk = cumsum(cases)) %>%
dplyr::filter(uk > 100) %>%
dplyr::select(-cases, -date)
df_uk$index <- 1:nrow(df_uk)
df_fr <- coronavirus %>% dplyr::filter(type == "confirmed", Country.Region == "France") %>%
dplyr::group_by(date) %>%
dplyr::summarise(cases = sum(cases)) %>%
dplyr::ungroup() %>%
dplyr::arrange(date) %>%
dplyr::mutate(france = cumsum(cases)) %>%
dplyr::filter(france > 100) %>%
dplyr::select(-cases, -date)
df_fr$index <- 1:nrow(df_fr)
df_us <- coronavirus %>% dplyr::filter(type == "confirmed", Country.Region == "US") %>%
dplyr::group_by(date) %>%
dplyr::summarise(cases = sum(cases)) %>%
dplyr::ungroup() %>%
dplyr::arrange(date) %>%
dplyr::mutate(us = cumsum(cases)) %>%
dplyr::filter(us > 100) %>%
dplyr::select(-cases, -date)
df_us$index <- 1:nrow(df_us)
df_iran <- coronavirus %>% dplyr::filter(type == "confirmed", Country.Region == "Iran") %>%
dplyr::group_by(date) %>%
dplyr::summarise(cases = sum(cases)) %>%
dplyr::ungroup() %>%
dplyr::arrange(date) %>%
dplyr::mutate(iran = cumsum(cases)) %>%
dplyr::filter(iran > 100) %>%
dplyr::select(-cases, -date)
df_iran$index <- 1:nrow(df_iran)
df_sk <- coronavirus %>% dplyr::filter(type == "confirmed", Country.Region == "Korea, South") %>%
dplyr::group_by(date) %>%
dplyr::summarise(cases = sum(cases)) %>%
dplyr::ungroup() %>%
dplyr::arrange(date) %>%
dplyr::mutate(sk = cumsum(cases)) %>%
dplyr::filter(sk > 100) %>%
dplyr::select(-cases, -date)
df_sk$index <- 1:nrow(df_sk)
df_spain <- coronavirus %>% dplyr::filter(type == "confirmed", Country.Region == "Spain") %>%
dplyr::group_by(date) %>%
dplyr::summarise(cases = sum(cases)) %>%
dplyr::ungroup() %>%
dplyr::arrange(date) %>%
dplyr::mutate(spain = cumsum(cases)) %>%
dplyr::filter(spain > 100) %>%
dplyr::select(-cases, -date)
df_spain$index <- 1:nrow(df_spain)
df_trajectory <- df_china %>%
dplyr::left_join(df_iran, by = "index") %>%
dplyr::left_join(df_sk, by = "index") %>%
dplyr::left_join(df_us, by = "index") %>%
dplyr::left_join(df_fr, by = "index") %>%
dplyr::left_join(df_uk, by = "index") %>%
dplyr::left_join(df_spain, by = "index")
```
Summary
=======================================================================
Row
-----------------------------------------------------------------------
### confirmed {.value-box}
```{r, echo=FALSE}
valueBox(value = paste(format(sum(df$confirmed), big.mark = ","), "", sep = " "),
caption = "Total Confirmed Cases",
icon = "fas fa-user-check",
color = "#737373")
```
### active {.value-box}
```{r, echo=FALSE}
valueBox(value = paste(format(sum(df$unrecovered, na.rm = TRUE), big.mark = ","), " (",
round(100 * sum(df$unrecovered, na.rm = TRUE) / sum(df$confirmed), 1),
"%)", sep = ""),
caption = "Active Cases", icon = "fas fa-walking",
color = active_color)
```
### recovered {.value-box}
```{r,echo=FALSE}
valueBox(value = paste(format(sum(df$recovered, na.rm = TRUE), big.mark = ","), " (",
round(100 * sum(df$recovered, na.rm = TRUE) / sum(df$confirmed), 1),
"%)", sep = ""),
caption = "Recovered Cases", icon = "far fa-smile",
color = recovered_color)
```
### death {.value-box}
```{r,echo=FALSE}
valueBox(value = paste(format(sum(df$death, na.rm = TRUE), big.mark = ","), " (",
round(100 * sum(df$death, na.rm = TRUE) / sum(df$confirmed), 1),
"%)", sep = ""),
caption = "Death Cases",
icon = "far fa-frown",
color = death_color)
```
Row {data-height=300,data-width=450}
-----------------------------------------------------------------------
### Daily Cumulative Cases by Type
```{r, echo=FALSE}
plotly::plot_ly(df_daily, x = ~date, y = ~active_cum, name = 'Active', type = 'scatter', mode = 'none', stackgroup = 'one', fillcolor = "#3966ad") %>%
plotly::add_trace(y = ~recovered_cum, name = 'Recovered', fillcolor = "#269928") %>%
plotly::add_trace(y = ~death_cum, name = "Death", fillcolor = "#661d1b") %>%
plotly::layout(title = "",
xaxis = list(title = "",
showgrid = FALSE),
yaxis = list(title = "Cumulative Number of Cases",
showgrid = FALSE),
legend = list(x = 0.1, y = 0.9),
hovermode = "compare")
```
### Recovery and Death Rates by Country
```{r, echo=FALSE}
df_summary <-coronavirus %>%
# dplyr::filter(Country.Region != "Others") %>%
dplyr::group_by(Country.Region, type) %>%
dplyr::summarise(total_cases = sum(cases)) %>%
tidyr::pivot_wider(names_from = type, values_from = total_cases) %>%
dplyr::arrange(- confirmed) %>%
dplyr::filter(confirmed >= 25) %>%
dplyr::select(country = Country.Region, confirmed, recovered, death) %>%
dplyr::mutate(recover_rate = recovered / confirmed,
death_rate = death / confirmed)
df_summary %>%
DT::datatable(rownames = FALSE,
colnames = c("Country", "Confirmed", "Recovered", "Death", "Recovery Rate", "Death Rate"),
options = list(pageLength = nrow(df_summary), dom = 'tip')) %>%
DT::formatPercentage("recover_rate", 2) %>%
DT::formatPercentage("death_rate", 2)
```
Row {data-width=fill}
-----------------------------------------------------------------------
### Cases Distribution by Type (Top 25 Countries)
```{r daily_summary, echo=FALSE}
plotly::plot_ly(data = df[1:30,],
x = ~ country,
y = ~ unrecovered,
# text = ~ confirmed,
# textposition = 'auto',
type = "bar",
name = "Active",
marker = list(color = active_color)) %>%
plotly::add_trace(y = ~ recovered,
# text = ~ recovered,
# textposition = 'auto',
name = "Recovered",
marker = list(color = recovered_color)) %>%
plotly::add_trace(y = ~ death,
# text = ~ death,
# textposition = 'auto',
name = "Death",
marker = list(color = death_color)) %>%
plotly::layout(barmode = 'stack',
yaxis = list(title = "Total Cases (log scaled)",
type = "log"),
xaxis = list(title = ""),
hovermode = "compare",
margin = list(
# l = 60,
# r = 40,
b = 10,
t = 10,
pad = 2
))
```
Trends
=======================================================================
Column
-------------------------------------
### New Cases - Top 15 Countries (`r max(coronavirus$date)`)
```{r,echo=FALSE}
max_date <- max(coronavirus$date)
coronavirus %>%
dplyr::filter(type == "confirmed", date == max_date) %>%
dplyr::group_by(Country.Region) %>%
dplyr::summarise(total_cases = sum(cases)) %>%
dplyr::arrange(-total_cases) %>%
dplyr::mutate(country = factor(Country.Region, levels = Country.Region)) %>%
dplyr::ungroup() %>%
dplyr::top_n(n = 15, wt = total_cases) %>%
plotly::plot_ly(x = ~ country,
y = ~ total_cases,
text = ~ total_cases,
textposition = 'auto',
color = ~ country, showlegend = FALSE,
type = "bar") %>%
plotly::layout(yaxis = list(title = "Number of Cases"),
xaxis = list(title = ""),
margin = list(
l = 10,
r = 10,
b = 10,
t = 10,
pad = 2
))
```
### Recovery and Death Rates for Countries with at Least 5000 Cases
```{r,echo=FALSE}
coronavirus::coronavirus %>%
# dplyr::filter(Country.Region != "Others") %>%
dplyr::group_by(Country.Region, type) %>%
dplyr::summarise(total_cases = sum(cases)) %>%
tidyr::pivot_wider(names_from = type, values_from = total_cases) %>%
dplyr::arrange(- confirmed) %>%
dplyr::filter(confirmed >= 5000) %>%
dplyr::mutate(recover_rate = recovered / confirmed,
death_rate = death / confirmed) %>%
dplyr::mutate(recover_rate = dplyr::if_else(is.na(recover_rate), 0, recover_rate),
death_rate = dplyr::if_else(is.na(death_rate), 0, death_rate)) %>%
dplyr::ungroup() %>%
dplyr::mutate(confirmed_normal = as.numeric(confirmed) / max(as.numeric(confirmed))) %>%
plotly::plot_ly(y = ~ round(100 * recover_rate, 1),
x = ~ round(100 * death_rate, 1),
size = ~ log(confirmed),
sizes = c(5, 70),
type = 'scatter', mode = 'markers',
color = ~ Country.Region,
marker = list(sizemode = 'diameter' , opacity = 0.6),
hoverinfo = 'text',
text = ~paste("", Country.Region,
" Confirmed Cases: ", confirmed,
" Recovery Rate: ", paste(round(100 * recover_rate, 1), "%", sep = ""),
" Death Rate: ", paste(round(100 * death_rate, 1), "%", sep = ""))
) %>%
plotly::layout(yaxis = list(title = "Recovery Rate", ticksuffix = "%"),
xaxis = list(title = "Death Rate", ticksuffix = "%",
dtick = 1,
tick0 = 0),
hovermode = "closest")
```
Column
-------------------------------------
### Trajectory Plot - Major Countries
```{r,echo=FALSE}
plotly::plot_ly(data = df_trajectory) %>%
plotly::add_lines(x = ~ index,
y = ~ china,
name = "China", line = list(width = 2)) %>%
plotly::add_lines(x = ~ index,
y = ~ us,
name = "United States", line = list(width = 2)) %>%
plotly::add_lines(x = ~ index,
y = ~ uk,
name = "United Kingdom", line = list(width = 2)) %>%
plotly::add_lines(x = ~ index,
y = ~ france,
name = "France", line = list(width = 2)) %>%
plotly::add_lines(x = ~ index,
y = ~ iran,
name = "Iran", line = list(color = "orange", width = 2)) %>%
plotly::add_lines(x = ~ index,
y = ~ sk,
name = "South Korea", line = list(width = 2)) %>%
plotly::add_lines(x = ~ index,
y = ~ spain,
name = "Spain") %>%
plotly::layout(yaxis = list(title = "Cumulative Positive Cases",type = "log"),
xaxis = list(title = "Days since the total positive cases surpass 100"),
legend = list(x = 0.7, y = 0.3),
hovermode = "compare")
```
### Cases Status Update for `r max(coronavirus$date)`
```{r,echo=FALSE}
daily_summary <- coronavirus %>%
dplyr::filter(date == max(date)) %>%
dplyr::group_by(Country.Region, type) %>%
dplyr::summarise(total = sum(cases)) %>%
tidyr::pivot_wider(names_from = type, values_from = total) %>%
dplyr::arrange(-confirmed) %>%
dplyr::select(country = Country.Region, confirmed, recovered, death)
DT::datatable(data = daily_summary,
rownames = FALSE,
colnames = c("Country", "Confirmed", "Recovered", "Death"),
options = list(pageLength = nrow(daily_summary), dom = 'tip'))
```
Map
=======================================================================
**Map**
```{r,echo=FALSE}
cv_data_for_plot <- coronavirus %>%
dplyr::filter(cases > 0) %>%
dplyr::group_by(Country.Region,Province.State,Lat,Long,type) %>%
dplyr::summarise(cases = sum(cases)) %>%
dplyr::mutate(log_cases = 2 * log(cases)) %>%
dplyr::ungroup()
cv_data_for_plot.split <- cv_data_for_plot %>% split(cv_data_for_plot$type)
pal <- colorFactor(c("#bf7343", "#661d1b","#269928"), domain = c("confirmed", "death","recovered"),alpha = TRUE)
map_object <- leaflet() %>% addProviderTiles(providers$CartoDB.DarkMatter)
names(cv_data_for_plot.split) %>%
purrr::walk( function(df) {
map_object <<- map_object %>%
addCircleMarkers(data=cv_data_for_plot.split[[df]],
lng=~Long, lat=~Lat,
label=~as.character(cases),
color = ~pal(type),
stroke = FALSE,
fillOpacity = 0.8,
radius = ~log_cases,
popup = leafpop::popupTable(cv_data_for_plot.split[[df]],
feature.id = FALSE,
row.numbers = FALSE,
zcol=c("type","cases","Country.Region","Province.State")),
group = df,
clusterOptions = markerClusterOptions(removeOutsideVisibleBounds = F),
labelOptions = labelOptions(noHide = F,
direction = 'auto'))
})
map_object %>%
addLayersControl(
overlayGroups = names(cv_data_for_plot.split),
options = layersControlOptions(collapsed = FALSE)
)
```
Data
=======================================================================
```{r,echo=FALSE}
coronavirus %>%
dplyr::select(Date = date, Province = Province.State, Country = Country.Region, `Case Type` = type, `Number of Cases` = cases) %>%
DT::datatable(rownames = FALSE,
options = list(searchHighlight = TRUE,
pageLength = 20), filter = 'top')
```
About
=======================================================================
**COVID-19 dashboard**
This COVID-19 dashboard was created as the final assignment for the Data Analysis course at Utah Valley University, which is instructed by Dr. Zahn. The information here provides an overlook of the COVID-19 data by providing the user with graphs, figures, a map, etc., all of which were built using the Rmarkdown framework in R Studio
**Reproduction**
All data was obtained freely online. The code behind the dashboard is available [here](https://github.com/RamiKrispin/coronavirus_dashboard)
**Data**
The input data for this dashboard is the [coronavirus](https://github.com/RamiKrispin/coronavirus) R package (dev version). The data and dashboard is refreshed on a daily bases. The raw data pulled from the Johns Hopkins University Center for Systems Science and Engineering (JHU CCSE) Coronavirus [repository](https://github.com/RamiKrispin/coronavirus-csv)
**Packages**
* Dashboard interface - the [flexdashboard](https://rmarkdown.rstudio.com/flexdashboard/) package.
* Visualization - the [plotly](https://plot.ly/r/) package for the plots and [leaflet](https://rstudio.github.io/leaflet/) for the map
* Data manipulation - [dplyr](https://dplyr.tidyverse.org/), and [tidyr](https://tidyr.tidyverse.org/)
* Tables - the [DT](https://rstudio.github.io/DT/) package
**Useful Links**
* Icons - [Free Icons](https://fontawesome.com/icons?d=gallery)
* Maps - change the [map](https://github.com/leaflet-extras/leaflet-providers/blob/master/leaflet-providers.js)
* Plotly - helpful information for using the [plotly](https://plotly.com/r/reference/) function
* Flexdashboard - helpful information for using [flexdashboard](https://cran.r-project.org/web/packages/flexdashboard/flexdashboard.pdf)